<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.2 / SVN信息：$Id: class.JCAT_Friendship.php 1250 2009-02-07 04:53:17Z aleechou $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/




/**
 * 友元管理
 *
 * @author		alee
 * @access		public
 */
class JCAT_Friendship
{
	/**
	 * 检查友元关系是否成立
	 * 
	 * @access	public
	 * @param	$aWho=null	_JCAT_Caller	“谁”
	 * @param	$sForWhom	string			是 “谁的” 有元
	 * @static
	 * @return	bool
	 */
	static public function IsFriend( $sForWhom='' ) 
	{
		$aWhom = JCAT_Backtrace::GetCaller() ;
		if( $sForWhom==='' )
			$sForWhom = $aWhom->GetClass().'::'.$aWhom->GetFunction() ;
		
		self::AssertForWhomParam($sForWhom) ;
		
		$aWho = $aWhom->GetCaller() ;			
		JCAT_ASSERT::ASSERT_INSTANCE( $aWho, '_JCAT_Caller', JCAT_Language::SentenceEx('必须来自有效的访问','JCAT',null) ) ;
		
		
		list($sClass,$sFunctionName) = explode('::',$sForWhom) ;
		$sClass.= '::' ;
		
		// 检查 class 的友元
		if( isset(self::$arrFriendships[ $sClass ]) )
		{
			foreach( self::$arrFriendships[ $sClass ] as $aTarget )
			{
				if( $aTarget->IsFriend($aWho) )
					return true ;
			}
		}
		// echo $aWho->GetClass().'::'.$aWho->GetFunction() ;
		// 检查 方法/函数 的友元
		if( !empty($sFunctionName) and isset(self::$arrFriendships[ $sForWhom ]) )
		{
			foreach( self::$arrFriendships[ $sForWhom ] as $aTarget )
			{
				if( $aTarget->IsFriend($aWho) )
					return true ;
			}
		}
		
		return false ;
	}



	/**
	 * 将一个全局函数设为友元
	 * 
	 * @access	public
	 * @param	$sFunction		string	函数名称
	 * @param	$sForWhom=''	string	“谁的”
	 * @static
	 * @return	void
	 */
	static public function SetFriendlyFunction(  $sFunction,  $sForWhom ) 
	{
		self::AssertForWhomParam($sForWhom) ;
		self::$arrFriendships[ $sForWhom ][] = new _JCAT_FriendTarget(0,'',$sFunction) ;
	}



	/**
	 * 将一个类设为友元
	 * 
	 * @access	public
	 * @param	$sFunction		string	类名称
	 * @param	$sForWhom=''	string	“谁的”
	 * @static
	 * @return	void
	 */
	static public function SetFriendlyClass(  $sClass,  $sForWhom ) 
	{
		self::AssertForWhomParam($sForWhom) ;
		self::$arrFriendships[ $sForWhom ][] = new _JCAT_FriendTarget(0,$sClass,'') ;
	}



	/**
	 * 将一个方法设为 友元
	 * 
	 * @access	public
	 * @param	$sFunction		string	类名称
	 * @param	$sMethod		string	方法名
	 * @param	$sForWhom=''	string	“谁的”
	 * @static
	 * @return	void
	 */
	static public function SetFriendlyMethod(  $sClass,  $sMethod,  $sForWhom ) 
	{
		self::AssertForWhomParam($sForWhom) ;
		self::$arrFriendships[ $sForWhom ][] = new _JCAT_FriendTarget(0,$sClass,$sMethod) ;
	}



	/**
	 * 将一个包设为 友元
	 * 
	 * @access	public
	 * @param	$nPackageID	int	包ID
	 * @static
	 * @return	void
	 */
	static public function SetFriendlyPackage(  $nPackageID,  $sForWhom ) 
	{
		self::AssertForWhomParam($sForWhom) ;
		self::$arrFriendships[ $sForWhom ][] = new _JCAT_FriendTarget($nPackageID,'','') ;
	}


	static public function ClearFriend( $sForWhom )
	{
		self::AssertForWhomParam($sForWhom) ;
		self::$arrFriendships[ $sForWhom ] = array() ;
	}
	
	static public function Clear()
	{
		self::$arrFriendships = array() ;
	}
	

	static public function AssertForWhomParam($sForWhomParam)
	{
		if( !is_string( $sForWhomParam ) )
			throw new JCAT_Exception( JCAT_Language::SentenceEx('参数 $sForWhom  的类型必须为字符串','JCAT',null), JCAT_Exception::MakeExceptionCode(__CLASS__,1) ) ;

		if( !preg_match('/::/',$sForWhomParam) )
			throw new JCAT_Exception( JCAT_Language::SentenceEx('参数 $sForWhom  必须符合三种格式：“类名::”、 “类名::方法名” 或 “::函数名”(全局函数) ','JCAT',null), JCAT_Exception::MakeExceptionCode(__CLASS__,2) ) ;
	}

	// 属性 ///////////////////////////////////////////////////////////////////////////////

	/**
	 * 友元关系
	 * 
	 * @access	private
	 * @var		
	 * @static
	 */
	static private $arrFriendships = array() ;


}
/*macro_exception_code:2*/
?>